package piwan;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;

public class PlaneRenderer {
	static int tileSize=512;
	static double planeWidth = 20.0;
	static String defaultPlaneTexture = "gfx/highres.png";
	
	public PlaneRenderer( MainWindow gui ) {
		gl = gui.getGL();
		loadTexture(defaultPlaneTexture);
	}
	
	public void render() {
		gl.glCallList(displayList);
	}
	
	public void loadTexture(String fileName) {
		tex = null;
		System.gc();
		try {
			BufferedImage img = ImageIO.read( new File(fileName) );
			texcols = (int)Math.ceil((double)img.getWidth()/tileSize);
			texrows = (int)Math.ceil((double)img.getHeight()/tileSize);
			
			planeHeight=planeWidth/img.getWidth()*img.getHeight();
			double toWorld = planeWidth/img.getWidth(); 
			int lastColPixels = tileSize - (texcols*tileSize - img.getWidth());
			int lastRowPixels = tileSize - (texrows*tileSize - img.getHeight());
			if(lastColPixels == 0) lastColPixels = tileSize;
			if(lastRowPixels == 0) lastRowPixels = tileSize;
			tileWorldSize = toWorld*tileSize; //;
			lastColClip = lastColPixels*toWorld;
			lastRowClip = lastRowPixels*toWorld;
			tex = new Texture[texrows][texcols];
			
			for(int i=0;i<texrows;++i)
				for(int j=0;j<texcols;++j) {
					int rectw,recth;
					if( i == texrows-1 )
						recth = lastRowPixels;
					else
						recth = tileSize;
					
					if( j == texcols-1 )
						rectw = lastColPixels;
					else
						rectw = tileSize;
						
					BufferedImage sub = img.getSubimage(j*tileSize, i*tileSize, rectw, recth);
					
					tex[i][j] = TextureIO.newTexture(sub, false);
					tex[i][j].setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
					tex[i][j].setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
					sub=null;
					System.gc();
				}
		} catch( IOException e ) {
			MainWindow.die(e);
		}
		//img = null;
		System.gc();
		displayList = gl.glGenLists(1);
		gl.glNewList(displayList, GL.GL_COMPILE);
		performRender();
		gl.glEndList();
		
	}
	
	public void performRender() {
		double x1,x2,y1,y2;
		gl.glDisable(GL.GL_LIGHTING);
		gl.glEnable(GL.GL_TEXTURE_2D);
		
		gl.glColor4d(1.0,1.0,1.0,1.0);
		for(int i=0;i<texrows;++i)
			for(int j=0;j<texcols;++j) {
				x1 = j*tileWorldSize - planeWidth/2.0;
				y1 = i*tileWorldSize - planeHeight/2.0;
				
				if(i==texrows-1)
					y2 = y1 + lastRowClip;
				else
					y2 = y1 + tileWorldSize;
				
				if(j==texcols-1) 
					x2 = x1 + lastColClip;
				else
					x2 = x1 + tileWorldSize;


				tex[i][j].bind();
				
				gl.glBegin(GL.GL_QUADS);
				gl.glTexCoord2d(0.0,0.0);
				gl.glVertex3d(x1, 0.0, y1);
				gl.glTexCoord2d(1.0,0.0);
				gl.glVertex3d(x2, 0.0, y1);
				gl.glTexCoord2d(1.0,1.0);
				gl.glVertex3d(x2, 0.0, y2);
				gl.glTexCoord2d(0.0,1.0);
				gl.glVertex3d(x1, 0.0, y2);
				gl.glEnd();
			}
		
	}
	
	private Texture tex[][] = null;
	private GL gl = null;
	private double tileWorldSize,lastColClip,lastRowClip;
	private double planeHeight;
	private int texrows,texcols;
	private int displayList=0;
}
